import WechatJSSDK from "wechat-jssdk/dist/client.umd";
import { getWechatConfig, wechatAuth } from "@api/public";
import { randomExtractAgain, queryTaskFinished, taskFinish } from "@api/user";
import { parseQuery } from "@utils";
import cookie from "@utils/store/cookie";
import store from "@/store";
import dayjs from "dayjs";

const STATE_KEY = "wx_authorize_state";
const WX_AUTH = "wx_auth";
const BACK_URL = "login_back_url";
const LOGINTYPE = "loginType";
let instance;
let wechatObj;

export default function wechat() {
  return new Promise((resolve, reject) => {
    if (instance) return resolve(instance);
    getWechatConfig()
      .then(res => {
        const _wx = WechatJSSDK(res.data);
        wechatObj = _wx;
        _wx
          .initialize()
          .then(() => {
            instance = _wx;
            instance.initConfig = res.data;
            resolve(instance);
          })
          .catch(reject);
      })
      .catch(err => {
        console.log(err);
        reject(err);
      });
  });
}

export function clearAuthStatus() {
  cookie.remove(WX_AUTH);
  cookie.remove(STATE_KEY);
}

export function oAuth() {
  if (cookie.has(WX_AUTH) && store.state.app.token) return;
  const { code } = parseQuery();
  if (!code) return toAuth();
}

export function auth(code) {
  return new Promise((resolve, reject) => {
    let loginType = cookie.get(LOGINTYPE);
    //if (state !== cookie.get(STATE_KEY)) return reject();
    wechatAuth(code, parseInt(cookie.get("spread")), loginType)
      .then(({ data }) => {
        const expires_time = dayjs(data.expires_time);
        const newTime = Math.round(new Date() / 1000);
        store.commit("LOGIN", data.token, expires_time - newTime);
        cookie.set(WX_AUTH, code, expires_time);
        cookie.remove(STATE_KEY);
        loginType && cookie.remove("loginType");
        resolve();
      })
      .catch(reject);
  });
}

export function toAuth() {
  wechat().then(wx => {
    location.href = getAuthUrl(wx.initConfig.appId);
  });
}

function getAuthUrl(appId) {
  const redirect_uri = encodeURIComponent(
    `${location.origin}/auth/` +
      encodeURIComponent(
        encodeURIComponent(
          cookie.has(BACK_URL)
            ? cookie.get(BACK_URL)
            : location.pathname + location.search
        )
      )
  );
  cookie.remove(BACK_URL);
  const state = encodeURIComponent(
    ("" + Math.random()).split(".")[1] + "authorizestate"
  );
  cookie.set(STATE_KEY, state);
  return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_userinfo&state=${state}#wechat_redirect`;
}

function toPromise(fn, config = {}) {
  return new Promise((resolve, reject) => {
    fn({
      ...config,
      success(res) {
        resolve(res);
      },
      fail(err) {
        reject(err);
      },
      complete(err) {
        reject(err);
      },
      cancel(err) {
        reject(err);
      }
    });
  });
}

export function pay(config) {
  return toPromise(instance.chooseWXPay, config);
}

export function openAddress() {
  return new Promise((resolve, reject) => {
    wechatEvevt("openAddress", {})
      .then(res => {
        console.log(res);
        resolve(res);
      })
      .catch(res => {
        console.log(res);
        if (res.is_ready) {
          res.wx.openAddress({
            fail(res) {
              reject(res);
            },
            success(res) {
              resolve(res);
            }
          });
        } else {
          reject(res);
        }
      });
  });
}

export function openShareAll(config) {
  config || {};
  config.type = config.type == undefined ? "link" : config.type;
  return new Promise(resolve => {
    getWechatConfig().then(res => {
      wechatObj.signSignature({
        nonceStr: res.data.nonceStr,
        signature: res.data.signature,
        timestamp: res.data.timestamp
      });
      instance = wechatObj.getOriginalWx();
      instance.initConfig = res.data;
      instance.ready(() => {
        openShareAppMessage(config)
        openShareTimeline(config)
        // instance.updateAppMessageShareData(config);
        // instance.updateTimelineShareData(config);
        resolve();
      });
    });
  });
}

// 旧版分享完成回调触发事件
const decide = (type) => {
  console.log('decide function', type, store)
  switch (type) {
    case 'commodity':
      console.log('是商品呀呀')
      store.commit('SHARE_SUCCESS', 'COMMODITY');
      console.log('任务是否完成', store.getters);
      if (!store.getters.taskState.share) {
        queryTaskFinished('share_goods').then(res => {
          console.log('查询分享任务', res);
          if (!(+res.data.isok)) {
            taskFinish('share_goods', res.data.reward).then(res => {
              console.log('设置分享任务完成', res);
              store.commit('TASK_FINISHED', 'share');
            });
          } else {
            store.commit('TASK_FINISHED', 'share');
          }
        }); 
      }
      return;
    case 'sign':
      console.log('是签到呀呀')
      randomExtractAgain().then(res => {
        console.log('签到，再挖一次', res);
        store.commit('SHARE_SUCCESS', 'SIGN');
      });
      return;
    case 'privilege':
      store.commit('SHARE_SUCCESS', 'PRIVILEGE');
      return;
    case 'reduction':
      console.log('是立减金呀呀')
      store.commit('SHARE_SUCCESS', 'REDUCTION');
      return;
  }
}
export function openShareAppMessage(config, type='') {
  console.log('好友分享ready', config)
  if (instance.onMenuShareAppMessage) {
    console.log('触发旧的好友分享接口');
    instance.onMenuShareAppMessage({
      title: config.title,
      desc: config.desc, 
      link: config.link,
      imgUrl: config.imgUrl,
      success: function () {
        console.log('好友分享回调成功');
        if (!type) return;
        decide(type);
      },
      fail: function (err) {
        console.log('fail',err)
      }
    });
  } else {
    console.log('excuese me?????????????????????????????  friend share', config);
    instance.updateAppMessageShareData(config);
  }
}

export function openShareTimeline(config, type='') {
  console.log('朋友圈分享ready', config)
  if (instance.onMenuShareTimeline) {
    console.log('触发旧的朋友圈分享接口');
    instance.onMenuShareTimeline({
      title: config.title,
      link: config.link,
      imgUrl: config.imgUrl,
      success: function () {
        console.log('朋友圈分享回调成功');
        if (!type) return;
        decide(type);
      }
    });
  } else {
    console.log('excuese me?????????????????????????????  timeline share', config);
    instance.updateTimelineShareData(config);
  }
}

/**
 * 公众号事件
 * @param name 事件名
 * @param config 配置
 * @returns {Promise<unknown>}
 */
export function wechatEvevt(name, config) {
  return new Promise((resolve, reject) => {
    let wx;
    let configDefault = {
      fail(res) {
        console.log(res);
        if (wx) return reject({ is_ready: true, wx: wx });
        getWechatConfig().then(res => {
          wechatObj.signSignature({
            nonceStr: res.data.nonceStr,
            signature: res.data.signature,
            timestamp: res.data.timestamp
          });
          wx = wechatObj.getOriginalWx();
          reject({ is_ready: true, wx: wx });
        });
      },
      success(res) {
        resolve(res);
      }
    };
    Object.assign(configDefault, config);
    if (typeof instance !== "undefined") {
      instance.ready(() => {
        if (typeof name === "object") {
          name.forEach(item => {
            instance[item] && instance[item](configDefault);
          });
        } else instance[name] && instance[name](configDefault);
      });
    } else {
      getWechatConfig().then(res => {
        const _wx = WechatJSSDK(res.data);
        _wx.initialize().then(() => {
          instance = _wx.getOriginalWx();
          instance.ready(() => {
            if (typeof name === "object") {
              name.forEach(item => {
                instance[item] && instance[item](configDefault);
              });
            } else instance[name] && instance[name](configDefault);
          });
        });
      });
    }
  });
}

export function ready() {
  return new Promise(resolve => {
    if (typeof instance !== "undefined") {
      instance.ready(() => {
        resolve(instance);
      });
    } else {
      wechat()
      // getWechatConfig().then(res => {
      //   const _wx = WechatJSSDK(res.data);
      //   _wx.initialize().then(() => {
      //     instance = _wx.wx;
          
      //     instance.ready(() => {
      //       resolve(instance);
      //     });
      //   });
      // });
    }
  });
}
